/**
 * 淘宝店铺评分数据记录侧边栏组件
 */

/**
 * 抖音店铺评分数据记录侧边栏组件
 */

import { StyleProvider } from "@ant-design/cssinjs"
import { FormOutlined } from "@ant-design/icons"
import cssText from "data-text:~/assets/css/dataScreenV2.css"
import antdResetCssText from "data-text:antd/dist/reset.css"
import moment from "moment"
import type {
  PlasmoCSConfig,
  PlasmoGetInlineAnchor,
  PlasmoGetShadowHostId
} from "plasmo"
import React, { useEffect, useState } from "react"

import { usePort } from "@plasmohq/messaging/hook"
import { useStorage } from "@plasmohq/storage/dist/hook"

import { ThemeProvider } from "~theme"
import DyShopScoreDataDetailModal from "~ui_components/DyShopScoreDataDetailModal"
import { _callApi } from "~utils/tools"

// 注入配置
export const config: PlasmoCSConfig = {
  matches: [
    // 淘宝千牛商家页面
    "https://myseller.taobao.com/home*"
  ],
  run_at: "document_start"
}

// 注入样式
export const getStyle = () => {
  const style = document.createElement("style")
  style.textContent = cssText + antdResetCssText
  return style
}

// 注入的shadow dom的id
export const HOST_ID = "tb-shop-score-tool"
export const getShadowHostId: PlasmoGetShadowHostId = () => HOST_ID

// export const getRootContainer = () => document.getElementById("app")
export const getInlineAnchor: PlasmoGetInlineAnchor = async () => {
  return {
    element: document.querySelector(
      "div[class^='iconsMenuContainer']"
    ),
    insertPosition: "afterbegin"
  }
}

// 组件定义
const TbShopScoreToolbar: React.FC = () => {
  // 评分数据处理port
  const scoreData = usePort("tbShopScoreData")
  // 数据完整性百分比
  const [dataCompleteRate, setDataCompleteRate] = useState<string>("0")
  // 用户是否登录
  const [userLogin] = useStorage("isLogin", false)
  const [showDetailModal, setShowDetailModal] = useState<boolean>(false)
  // 异常信息记录
  const [exceptionTxt, setExceptionTxt] = useState("")

  // 网络请求拦截事件响应
  // window hijackTbEvent响应方法
  const eventFunc = (
    event: CustomEvent<{
      api: string
      data: any
    }>
  ) => {
    // 直接转发到ports处理
    scoreData.send({ ...event.detail, action: "inspect" })
  }

  // 通过IFrame捕获评分数据
  const handleFetchDataByIFrame = (nodeId: undefined | number) => {
    // 初始化数据
    scoreData.send({ action: "clear" })
    // 创建iframe拦截捕获数据
    return new Promise(async (resolve) => {
      const detailUrl =
        "https://myseller.taobao.com/home.htm/voc/newTask/serverReport"
      // 使用iframe获取
      const iframe = document.createElement("iframe")
      // 将 iframe 移动到视口之外
      iframe.style.position = "absolute"
      iframe.style.left = "-9999px"
      iframe.style.top = "0px"
      iframe.src = detailUrl
      iframe.id = "fetch-iframe-" + (nodeId || "overview")
      // 处理 iframe 加载错误
      iframe.onerror = () => {
        resolve(new Error("Failed to load iframe"))
      }

      // 选择iframe中的 ul class="next-tabs-nav"下 li元素列表
      iframe.onload = async () => {
        // console.log("iframe加载完成")
        const iframeDoc = iframe.contentDocument || iframe.contentWindow.document
        const tabs = iframeDoc.querySelectorAll("ul.next-tabs-nav li")
        // 如果 tabs 存在，模拟点击
        if (tabs.length > 0) {
          // 从第二个开始
          for (let i = 1; i < tabs.length; i++) {
            // 确保tab是可点击的, 转换类型
            const tab = tabs[i] as HTMLElement
            tab.click()
            // 等待0.3秒
            await new Promise(resolve => setTimeout(resolve, 300))
          }
        }
      }

      // 超时处理，定时30秒
      const eventTimeout = setTimeout(() => {
        // console.log("触发iframe超时事件")
        deleteIframeEventHandler()
        setExceptionTxt("数据抓取超时，请重试")
      }, 30000)

      // 拦截结束事件处理
      const deleteIframeEventHandler = () => {
        // console.log("触发删除iframe事件")
        clearTimeout(eventTimeout)
        // 移除
        iframe.remove()
        window.removeEventListener(
          "tbScoreIframeDelete",
          deleteIframeEventHandler
        )
        return resolve(true)
      }

      window.addEventListener("tbScoreIframeDelete", deleteIframeEventHandler)

      document.body.appendChild(iframe)
    })
  }

  // 获取数据键值总量
  const getKeysCount = async () => {
    const { data } = await _callApi("getKeysCountForDss", { shop_type: "tb" })
    scoreData.send({ action: "setKeys", data: data || 0 })
  }

  // 挂载事件监听
  useEffect(() => {
    // 获取数据键总量
    getKeysCount().then()
    // 挂载ui到服务
    // 初始化后台数据
    scoreData.send({ action: "clear" })
    // 监听hijackEvent事件
    window.addEventListener("hijackTbEvent", eventFunc)
    return () => {
      // 卸载事件监听
      window.removeEventListener("hijackTbEvent", eventFunc)
    }
  }, [])

  // 数据抓取按钮触发方法
  const handleCaptureData = async () => {
    setExceptionTxt("数据抓取中...")
    await handleFetchDataByIFrame(null)
  }

  // 数据显示对话框点击显示
  const handleShowDetailModal = () => {
    setShowDetailModal(true)
  }

  // 数据显示对话框关闭方法
  const handleClose = () => {
    setShowDetailModal(false)
  }

  // 数据清空方法
  const handleClear = () => {
    scoreData.send({
      action: "clear"
    })
    setExceptionTxt(``)
  }

  useEffect(() => {
    const rate = scoreData.data?.rate || "0"
    if (Number(rate) >= 100) {
      // 数据完整，触发删除iframe事件
      window.dispatchEvent(new Event("tbScoreIframeDelete"))
      // 设置结束信息
      // 数据日期
      const scoreDate = scoreData.data?.data["日期"] || ""
      setExceptionTxt(`数据抓取完成! 数据日期：【${scoreDate}】`)
    }
    // 数据完整率
    setDataCompleteRate(rate)
  }, [scoreData.data])

  return (
    <ThemeProvider>
      <StyleProvider container={document.getElementById(HOST_ID).shadowRoot}>
        {userLogin ? (
          <div
            className={
              "dy-shop-score-tool-wrapper tb-shop-score-tool-wrapper-fixed"
            }>
            <div className={"button-item"} onClick={handleShowDetailModal}>
              <FormOutlined />
            </div>
            {/*文字描述*/}
            <div className={"button-text"}>
              <span>评分数据</span>
            </div>
            {/*数据完整度*/}
            <div className={"button-tip"}>
              <span>{dataCompleteRate}%</span>
            </div>
          </div>
        ) : null}
        <DyShopScoreDataDetailModal
          shopType={"tb"}
          keys={scoreData?.data?.keysList}
          showDetailModal={showDetailModal}
          handleClose={handleClose}
          dataObject={scoreData?.data?.data}
          dataCompleteRate={dataCompleteRate}
          exceptionTxt={exceptionTxt}
          handleClear={handleClear}
          handleCapture={handleCaptureData}
        />
      </StyleProvider>
    </ThemeProvider>
  )
}

export default TbShopScoreToolbar
